#!/usr/bin/env python3

import argparse
import os
import sys

def merge(dest, files):
    '''
    Merge the content of all files into the file dest.

    The first line of each file is an optional section header in the form
    e.g.
       ! model =  keycodes
    Where two sections have identical headers, the second header is skipped.
    '''

    sections = {}
    section_names = []  # let's write out in the rough order of the Makefile.am
    for partsfile in files:
        # files may exist in srcdir or builddir, depending whether they're
        # generated
        path = partsfile[0] if os.path.exists(partsfile[0]) else partsfile[1]

        with open(path) as fd:
            header = fd.readline()
            if header.startswith('! '):
                # if we have a file that belongs to a section,
                # keep it for later sorted writing
                paths = sections.get(header, [])
                paths.append(path)
                sections[header] = paths
                if header not in section_names:
                    section_names.append(header)
            else:
                dest.write(header)
                dest.write(fd.read())

    for header in section_names:
        dest.write('\n')
        dest.write(header)
        for f in sections[header]:
            with open(f) as fd:
                fd.readline()  # drop the header
                dest.write(fd.read())


if __name__ == '__main__':
    parser = argparse.ArgumentParser('rules file merge script')
    parser.add_argument('dest', type=str)
    parser.add_argument('srcdir', type=str)
    parser.add_argument('builddir', type=str)
    parser.add_argument('files', nargs='+', type=str)
    ns = parser.parse_args()

    with open(ns.dest, 'w') as fd:
        basename = os.path.basename(sys.argv[0])
        fd.write('// DO NOT EDIT THIS FILE - IT WAS AUTOGENERATED BY {} FROM rules/*.part\n'.format(basename))
        fd.write('//\n')
        ftuple = lambda f: (os.path.join(ns.builddir, f), os.path.join(ns.srcdir, f))
        merge(fd, [ftuple(f) for f in ns.files])
